const http = require('http');
const path = require('path');
const Koa = require('koa');
const koaStatic = require('koa-static');
const koaBody = require('koa-body');
const koaSession = require('koa-session');
const MongooseStore = require('koa-session-mongoose');
const config = require(`./config/${ process.env.ENV }.json`);
const log = require('./lib/log');
const { loadController, loadSocketController, loadRouter, loadService } = require('./lib/loader');
const Router = require('./lib/router');
const { Io } = require('./lib/io');
const { Consul } = require('./lib/consul');
const { watch } = require('./monitor');
const koaApp = new Koa();
const server = http.Server(koaApp.callback());

require('./lib/mongo');

const store = new MongooseStore();

exports.store = store;

koaApp.use(koaSession({
  key: 'login-session',
  resave: false,
  store,
  sameSite: null,
  saveUninitialized: false,
  signed: false,
}, koaApp));

koaApp.use(koaStatic(path.join(__dirname, './public')));
koaApp.use(koaBody());

const consul = new Consul(process.env.CONSUL_ADDR || config.consulAddr, process.env.CONSUL_TOKEN || config.consulToken);
watch(consul);

exports.serverPromise = new Promise(async (resolve) => {
  const app = { router: new Router(), io: new Io(server) };
  app.service = await loadService(path.join(__dirname, './service'));
  app.controller = await loadController(path.join(__dirname, './controller'), app.service);
  app.socketController = await loadSocketController(path.join(__dirname, './socket/controller'), app.service);
  await loadRouter(path.join(__dirname, './router'), app);
  koaApp.use(async (ctx, next) => {
    ctx.log = log.request;
    ctx.consul = consul;
    await next();
  });
  koaApp.use(app.router.routes());
  koaApp.use(app.router.allowedMethods());
  config.port = process.env.PORT || config.port;
  resolve([
    server.listen(config.port, () => {
      log.app.info(`启动成功，监听端口${ config.port }...`);
    }),
    consul,
  ]);
});